import serial
import pynmea2
import time

import requests
import json

# zhh 自己编写的文件
import config


# 创建gps串口的句柄
SER = serial.Serial("/dev/ttyUSB0", 9600 )  

'''
function:
  从串口读取gps数据，和服务器查询到的站点的gps数据比对，如果距离达到一定程度，则判定达到(驶出)站点，此时，向服务器发送到达某站点的信息
 （这种方法彻底隔绝了服务器和树莓派之间直接交换gps数据的方式）

向服务发送的到站的报文格式：
{'driver_id': 'xxxxxxxx', 'bus_id': 'xxxxxx', 'platform_name': '.....'}

服务器返回报文：
{'driver_id': 'xxxxxxxx', 'bus_id': 'xxxxxx','type': 'true/false'}
'''
def gps_send():

    ret_num = platform_query()  # 首先向服务器查询所有站点信息
    if ret_num < 2:
        print('站点信息错误，线程终止')
        return
    else:
        while(True):                                  # 循环的，每个一定时间读取gps数据，直到挑选到我们需要的那一行，然后进行站点距离判断

            line = str(str(SER.readline())[2:])       # 头部的  b‘ 两个字符不要
            if line.startswith('$GPRMC'):             # 寻找有地理坐标的那一行数据（使用gprmc）
                line = line.replace('\\r\\n\'', '')   # 去除字符串末尾的无用字符
                rmc = pynmea2.parse(line)             # 调库，解析

                config.OLD_LONGITUDE = config.LONGITUDE  # 保存旧的经纬度
                config.OLD_LATITUDE = config.LATITUDE
                config.LONGITUDE = rmc.longitude      # 获取新的经纬度
                config.LATITUDE = rmc.latitude

                ret_plat_num = come_platform()        # 计算到达的站点的下标
                if ret_plat_num != -1:                # != -1 说明到达了新站点
                    json_context = {}
                    json_context['driver_id'] = config.DRIVER_ID
                    json_context['bus_id'] = config.BUS_ID
                    json_context['platform_name'] = config.platform_name[ret_plat_num]

                    response = requests.post(url=config.platform_arrive_URL, json=json_context)  # 向服务器发送到达站点的信息
                    ret_type = json.loads(response.text).get('type')
                    print(ret_type)



'''
function：
    车辆入站的距离判断
return:
    车辆即将到达的站点的序号（如果没有到达任何站，或者任然还没出站，则返回-1）
'''
def come_platform():

    thresh_2 = config.THRESHOLD ** 2            # 距离阈值的平方
    plat_num = len(config.platform_name)        # 站点个数

    for i in range(plat_num):
        distance_2 = ((config.LONGITUDE - config.platform_longitude[i]) ** 2) + ((config.LATITUDE - config.platform_latitude[i]) ** 2)
    
        if distance_2 < thresh_2:           # 距离小于域值，说明到站
            if i == config.NOW_PLATFORM:    # 和当前站点相同，则忽略
                continue
            else:                           # 和当前站点不同，则说明到达一个新站点
                return i
        return -1                           # 遍历一圈，没到达任何新站点，则返回-1                       



'''
function: 
  1.查询站点的gps信息（树莓派开机时，查询一次，写入config文件中platform_name列表保存）

  2.使用post请求查询，查询的参数是：车牌号，驾驶员id
  （服务器逻辑：根据当前时间，比较该辆车，在该时段，应该执行什么线路）
  3.函数返回值
    站点的个数
  4.车辆未初始化前，不得传送gps数据

上传的报文：
{'driver_id': 'xxxxxxxx', 'bus_id': 'xxxxxx'}

服务器返回的报文(一个包含多个字典的列表)：
[ 
  {'platform':'name****', 'longitude':118.222, 'latitude':45.365},
  {'platform':'', 'longitude':, 'latitude':},
  {  }
  ...  
]
注：服务器返回的站点的列表顺序，必须是路线上站点的顺序，不能是乱序的站点，否则判断机制会出错

'''
def platform_query():
  
    while(True):                                                           # 如果当前车辆没有初始化，则隔一段时间，再重新查询
        if config.BUS_ID != config.blank:
            break
        else:
            time.sleep(1)
    
    json_platform = {}                                                     # 待发送的json报文
    json_platform['driver_id'] = config.DRIVER_ID
    json_platform['bus_id'] = config.BUS_ID
    
    response = requests.post(url=config.platform_URL, json=json_platform)  # 上传至服务器验证（阻塞）,同时接受返回回来的数据
    platform_list = json.loads(response.text)                              # 解析出来的是一个list，list中每个元素是一个字典

    for platform_dict in platform_list:                                    # 遍历列表中的每个字典，取出来，存储到config中的列表中去
        if ('platform' in platform_dict) and ('longitude' in platform_dict) and ('latitude' in platform_dict):  # 检查数据合法性
            config.platform_name.append(platform_dict['platform'])
            config.platform_longitude.append(platform_dict['longitude'])
            config.platform_latitude.append(platform_dict['latitude'])

    return len(config.platform_name)

    

if __name__ == "__main__":
    config.BUS_ID = '黑1234'
    gps_send()
    print(config.platform_name)
    print(config.platform_longitude)
    print(config.platform_latitude)


    # gps_get_once()
    # print(LONGITUDE)
    # print(LATITUDE)

    # gps_lists = gps_get_num(5)
    # for list in gps_lists:
    #     print(list[0])
    #     print(list[1])

    # gps_list2 = gps_get_once()
    # print(gps_list2[0])
    # print(gps_list2[1])

    # count = 0
    # while(count<20):
    #     list1 = gps_get_once()
    #     print(list1)
    #     count = count +1
    
    



'''
************************ 以下是废弃代码 **********************
'''
# 最终形态函数
# 每隔一定时间（自设），采集一次GPS数据，然后发送给后端的服务器


# 用于后台线程，长时间运行，采集数据信息，并且存在全局变量中,等待别的代码读取经纬度，然后
def gps_run():
    while(True):
        line = str(str(SER.readline())[2:])       # 头部的  b‘ 两个字符不要           # read 是阻塞方法
        if line.startswith('$GPRMC'):             # 寻找有地理坐标的那一行数据（使用gprmc）
            line = line.replace('\\r\\n\'', '')   # 去除字符串末尾的无用字符
            rmc = pynmea2.parse(line)             # 调库，解析
            global LONGITUDE
            LONGITUDE = rmc.longitude              # 获取经度
            global LATITUDE
            LATITUDE = rmc.latitude                # 获取纬度



# 获取一次gps位置信息：
# 获取gps报文，解析报文，将经纬度写入全局变量，同时返回一个list
def gps_get_once():
    gps_list = []
    while(True):
        line = str(str(SER.readline())[2:])       # 头部的  b‘ 两个字符不要
        #print(line)
        if line.startswith('$GPRMC'):             # 寻找有地理坐标的那一行数据（使用gprmc）
            line = line.replace('\\r\\n\'', '')   # 去除字符串末尾的无用字符
            #print(line)
            rmc = pynmea2.parse(line)             # 调库，解析
            gps_list.append(rmc.longitude)            # 获取经度
            gps_list.append(rmc.latitude)             # 获取纬度
            global LONGITUDE
            LONGITUDE = rmc.longitude              # 获取经度
            global LATITUDE
            LATITUDE = rmc.latitude                # 获取纬度
            #print("采集结束")
            return gps_list


# -----------------------------------------  以下代码用不到 ---------------------------------------------------------------------


# 获取指定次数个gps位置信息：
# 返回一个二维列表
# def gps_get_num(num):
#     count = 0
#     gps_list = [ ]
#     while(True):
#         line = str(str(SER.readline())[2:])       # 头部的  b‘ 两个字符不要
#         print(line)
#         if line.startswith('$GPRMC'):             # 寻找有地理坐标的那一行数据（使用gprmc）
#             line = line.replace('\\r\\n\'', '')   # 去除字符串末尾的无用字符
#             print(line)
#             rmc = pynmea2.parse(line)             # 调库，解析
#             gps_list.append([rmc.longitude, rmc.latitude])  # 获取经度,获取纬度
#             print("****************** type :  " + str(type(rmc.longitude)))
#             print(gps_list)
#             count = count + 1
#             if (count == num):
#                 print("采集结束")
#                 return gps_list




